package dao

import models.Tables._
import play.api.db.slick.{DatabaseConfigProvider, HasDatabaseConfigProvider}
import shared.pojo.Sample.FreezerInfo
import slick.jdbc.JdbcProfile

import javax.inject.{Inject, Singleton}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
@Singleton
class SampleDao @Inject()(protected val dbConfigProvider: DatabaseConfigProvider) extends
  HasDatabaseConfigProvider[JdbcProfile] {


  import utils.MyPostgresProfile.api._
  import com.github.tototoshi.slick.MySQLJodaSupport._

  type MyRow = SampleRow
  val table = Sample

  def insert(row: MyRow) = {
    db.run(table += row)
  }

  def insertOrUpdate(row: MyRow) = {
    db.run(table.insertOrUpdate(row))
  }

  def selectAll = db.run(table.sortBy(_.updateTime.desc).result.map(_.toList))

  def selectAllId = db.run(table.map(_.id).result.map(_.toList))

  def selectAll(ids: List[String]) = db.run(table.filter(_.id.inSetBind(ids)).
    result.map(_.toList))

  def selectAll(freezerInfo: FreezerInfo) = db.run(table.filter { x =>
    val fi = x.freezerInfo
    fi.+>>("freezerNumber") === freezerInfo.freezerNumber &&
      fi.+>>("freezerLayerNumber") === freezerInfo.freezerLayerNumber
  }.result.map(_.toList))

  def updates(rows: Seq[MyRow]): Future[Unit] = {
    val action = DBIO.sequence(
      rows.map { row =>
        table.insertOrUpdate(row)
      }
    ).transactionally
    db.run(action).map(_ => ())
  }

  def deleteById(id: String): Future[Unit] = db.run(table.filter(_.id === id).delete).map(_ => ())

  def selectById(id: String) = db.run(table.
    filter(_.id === id).result.head)

  def selectByIdOp(id: String) = db.run(table.
    filter(_.id === id).result.headOption)

  def update(row: MyRow): Future[Unit] = db.run(table.filter(_.id === row.id).update(row)).
    map(_ => ())

  def idExist(id: String) = db.run(table.
    filter(_.id === id).exists.result)

  def existIds(ids: List[String]) = db.run(table.
    filter(_.id.inSetBind(ids)).map(_.id).result.map(_.toList))

  def existFreezer(id: String, freezer: FreezerInfo) = db.run(table.
    filter { x =>
      x.freezerInfo.+>>("freezerNumber") === freezer.freezerNumber &&
        x.freezerInfo.+>>("freezerLayerNumber") === freezer.freezerLayerNumber &&
        x.freezerInfo.+>>("rowNumber") === freezer.rowNumber &&
        x.freezerInfo.+>>("colNumber") === freezer.colNumber &&
        x.id =!= id
    }.exists.result)

}
